home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / advancec.arc / MENU.C < prev    next >
Text File  |  1992-01-24  |  6KB  |  256 lines

  1. /*
  2.     menu.c
  3.  
  4.     menu manager routines and variables
  5. */
  6.  
  7. #include "usrif.h"
  8. #undef   NULL
  9. #include "stdio.h"
  10.  
  11. /* global variables */
  12. extern  rect_t  screen;
  13. extern  vport_t *the_port;
  14. extern  point_t cursor;
  15.  
  16. /* menu border in pixels */
  17. #define BDR 3
  18.  
  19. /* menu text height in pixels */
  20. #define TH 12
  21.  
  22. int     pop_up_menu( num_items, items)
  23. int     num_items;
  24. char    *items[];
  25. {
  26. char    *look, *animate_seg();
  27. text_t  *t[MAX_MENUS];
  28. rect_t  area, bmap;
  29. rect_t  *bbox, *text_bbox();
  30. int     i, h, w, mw = 0, x, y;
  31. seg_t   *menu;
  32. key_t   *key;
  33. void    save_bitmap(), restore_bitmap();
  34.  
  35.     /* determine maximum item width */
  36.     for(i = 0; i < num_items; i++)
  37.         {
  38.         bbox = text_bbox(items[i], LEFT, BOTTOM);
  39.         w = bbox->right -  bbox->left;
  40.         free(bbox);
  41.  
  42.         if(w > mw)
  43.             mw = w;
  44.         }
  45.  
  46.     /* determine size of menu */
  47.     h = (TH + 2 * BDR) * num_items + 2;
  48.     w = mw + 2 * BDR;
  49.  
  50.     /* determine location of menu */
  51.     x = cursor.x;    y = cursor.y;
  52.  
  53.     /* greater than left edge of screen? */
  54.     if(x > (w / 2 + BDR))
  55.         x -= w / 2;
  56.     else
  57.         x = w / 2 + BDR;
  58.  
  59.     /* less than right edge of screen? */
  60.     if( (x + w) > screen.right)
  61.         x -= w + BDR;
  62.     else
  63.         x = screen.right - w - BDR;
  64.  
  65.     /* greater than bottom edge of screen? */
  66.     if(y > (h / 2 + BDR))
  67.         y -= h / 2;
  68.     else
  69.         y = h / 2 + BDR;
  70.  
  71.     /* less than top edge of screen? */
  72.     if( (y + h) > screen.top)
  73.         y -= h + BDR;
  74.     else
  75.         y = screen.top - h - BDR;
  76.  
  77.  
  78.     set_rect(&area, x, y, x + w, y + h);
  79.     set_rect(&bmap, x - 1, y - 1, x + w + 1, y + h + 1);
  80.  
  81.     cr_seg("menu");
  82.         add_attr(RESET);
  83.         add_attr(FILL);
  84.         add_rect(copy_rect(&area));
  85.  
  86.         add_attr(NOFILL);
  87.         add_attr(BLACK);
  88.         add_rect(copy_rect(&area));
  89.  
  90.         for(i = 0; i < num_items; i++)
  91.             {
  92.             t[i] = inst_text(items[i],
  93.                 x + 2 + w / 2, y + 2 * BDR + i * (TH + 2 * BDR),
  94.                 MIDDLE, BOTTOM);
  95.  
  96. /*
  97.             If you want menu items left-justified,
  98.             use this text command:
  99.  
  100.             t[i] = inst_text(items[i],
  101.                 x + 2 * BDR, y + 2 * BDR + i * (TH + 2 * BDR),
  102.                 LEFT, BOTTOM);
  103. */
  104.  
  105.             add_text(t[i]);
  106.             }
  107.  
  108.     menu = cl_seg();
  109.  
  110.     /* save bit-map region where menu goes */
  111.     save_bitmap(&bmap);
  112.  
  113.     /* draw menu in bit map */
  114.     hide_cursor();
  115.     draw_seg(menu, the_port);
  116.  
  117.     /* re-adjust text bboxs to world space */
  118.     for(i = 0; i < num_items; i++)
  119.         {
  120.         set_rect(t[i]->bbox,
  121.             x + 1, y + i * (TH + 2 * BDR) + 1,
  122.             x - 3 + w, y + (i + 1) * (TH + 2 * BDR)) - 2;
  123.         }
  124.  
  125.     /* animate menu item selection */
  126.     show_cursor();
  127.     look = animate_seg(menu);
  128.     del_seg(menu);
  129.  
  130.     /* replace bit-map region */
  131.     restore_bitmap(&bmap);
  132.  
  133.     /* return selected item */
  134.     for(i = 0;i<num_items;i++)
  135.         if(strcmp(look, items[i]) == 0)
  136.             return(i);
  137.  
  138.     return(-1);
  139. }
  140.  
  141. text_t  *active = NULL;
  142.  
  143. char    *animate_seg(seg)
  144. seg_t   *seg;
  145. {
  146. char    *item;
  147. event_t *myevent;
  148. key_t   *test;
  149. text_t  *t;
  150.  
  151.     for(;;)
  152.         {
  153.         myevent = get_next_event();
  154.  
  155.         if(myevent->what == UP_BUTTON_EVENT)
  156.             {
  157.             if(active == NULL)
  158.                 return(NULL);
  159.             else
  160.                 {
  161.                 item = active->text;
  162.                 active = NULL;
  163.                 return(item);
  164.                 }
  165.             }
  166.         else if( pt_in_rect( seg->bbox, &(myevent->where) ))
  167.             {
  168.             test = seg->data;
  169.             while(test != NULL)
  170.                 {
  171.                 /* is text primitive */
  172.                 if(test->type == TEXT)
  173.                     {
  174.                     t = test->key.text;
  175.                     if(pt_in_rect(t->bbox, &(myevent->where)))
  176.                         {
  177.                         if(active == NULL)
  178.                             {
  179.                             /* make t the active text */
  180.                             xor_rect(t->bbox, FILL);
  181.                             active = t;
  182.                             }
  183.                         else if(active != t)
  184.                             {
  185.                             /* dim old text, make t active */
  186.                             xor_rect(active->bbox, FILL);
  187.                             xor_rect(t->bbox, FILL);
  188.                             active = t;
  189.                             }
  190.                         /* else do nothing */
  191.                         }
  192.                     }
  193.                 test = test->next;
  194.                 }
  195.             }
  196.         /* must be outside menu area */
  197.         else if(active != NULL)
  198.             {
  199.             xor_rect(active->bbox, FILL);
  200.             active = NULL;
  201.             }
  202.         }
  203. }
  204.  
  205. void    save_bitmap( rect )
  206. rect_t  *rect;
  207. {
  208.     hide_cursor();
  209.  
  210.     /*
  211.        save rectangular area of bit map
  212.     */
  213.  
  214.     show_cursor();
  215. }
  216.  
  217. void    restore_bitmap( rect )
  218. rect_t  *rect;
  219. {
  220.     hide_cursor();
  221.  
  222.     /*
  223.         restore rectangular area of bit map
  224.     */
  225.  
  226.     show_cursor();
  227. }
  228.  
  229. /*
  230.     Instead of using the segmentation system's
  231.     XOR feature, which clips and maps primitives,
  232.     use this function to provide the fastest
  233.     possible animation speed.
  234. */
  235.  
  236. xor_rect( rect, how)
  237. rect_t  *rect;
  238. int     how;
  239. {
  240.  
  241.     switch( how )
  242.         {
  243.         case FILL   :
  244.             /*
  245.                 Xor FILLed rectangle
  246.             */
  247.             break;
  248.  
  249.         case FRAME  :
  250.             /*
  251.                 Xor FRAMEd rectangle
  252.             */
  253.             break;
  254.         }
  255. }
  256.